package view;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSlider;
import javax.swing.border.BevelBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import model.FieldGenerator;
import model.PV;
import model.PathFinder;

public class MainWindow extends JFrame implements ActionListener {

	// SettingsPanel
	JPanel panelSettings;
	final int settingsWidth = 200;

	JPanel panelTitle;
	JPanel panelInfo1;
	JLabel labelFCosts;
	JLabel labelGCosts;
	JLabel labelHCosts;
	JPanel panelEditMode;
	ButtonGroup buttonGroupEditMode;
	JRadioButton radioObstacle;
	JRadioButton radioStart;
	JRadioButton radioEnd;
	JRadioButton radioClear;
	JPanel panelWorldEdit;
	JComboBox<String> comboWorldSize;
	String[] sizes = { "10x10", "20x20", "30x30" };
	JButton buttonGenerateWorld;
	JButton buttonClearWorld;
	String[] worldType = { "Clear", "Fill", "Random", "Structured" };
	JComboBox<String> comboWorldType;
	// JSpinner spinnerPercentageValue;
	String[] percentage = { "0", "5", "10", "15", "20", "25", "30", "35", "40", "45", "50", "55", "60", "65", "70", "75", "80", "85", "90", "95" };
	JComboBox<String> comboPercentage;

	JPanel panelSimulation;
	JSlider sliderSimSpeed;
	JButton buttonStartSim;
	JButton buttonEndSim;
	JPanel subPanelSimulation;
	JLabel labelSimSpeed;
	
	
	MainView panelMainView;
	Font font = new Font("MONOSPACED", Font.BOLD, 12);

	public MainWindow() {
		super();
		setSize(800, 622);
		setLocationRelativeTo(null);
		setTitle("FindPath");

		setResizable(false);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setLayout(null);

		// Settings
		panelSettings = new JPanel();
		panelSettings.setLocation(this.getWidth() - settingsWidth, 0);
		panelSettings.setSize(settingsWidth, this.getHeight());
		panelSettings.setBackground(Color.LIGHT_GRAY);
		panelSettings.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
		panelSettings.setLayout(new GridLayout(6, 0));

		// Title
		panelTitle = new JPanel();
		panelTitle.setBackground(Color.LIGHT_GRAY);
		panelTitle.setLayout(new GridLayout(2, 0));
		panelTitle.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
		JLabel labelSettings = new JLabel("   FindPath");
		labelSettings.setFont(new Font("Arial", Font.BOLD, 32));
		JLabel labelCopyright = new JLabel("          by Faruk Acibal and Christian Holzreuter");
		labelCopyright.setFont(new Font("Arial", Font.BOLD, 8));
		panelTitle.add(labelSettings);
		panelTitle.add(labelCopyright);
		panelSettings.add(panelTitle);

		// Info1
		panelInfo1 = new JPanel();
		panelInfo1.setBackground(Color.LIGHT_GRAY);
		panelInfo1.setLayout(new GridLayout(3, 0));
		panelInfo1.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
		labelFCosts = new JLabel(String.format("%-20s %n %s", " F Costs: ", "-"));
		labelFCosts.setFont(font);
		panelInfo1.add(labelFCosts);
		labelGCosts = new JLabel(String.format("%-20s %n %s", " G Costs: ", "-"));
		labelGCosts.setFont(font);
		panelInfo1.add(labelGCosts);
		labelHCosts = new JLabel(String.format("%-20s %n %s", " H Costs: ", "-"));
		labelHCosts.setFont(font);
		panelInfo1.add(labelHCosts);
		panelSettings.add(panelInfo1);

		// EditMode
		panelEditMode = new JPanel();
		panelEditMode.setBackground(Color.LIGHT_GRAY);

		panelEditMode.setLayout(new GridLayout(2, 2));
		panelEditMode.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));

		radioStart = new JRadioButton("Start (s)", false);
		radioStart.setFont(font);
		radioEnd = new JRadioButton("Target (t)", false);
		radioEnd.setFont(font);
		radioObstacle = new JRadioButton("Obst. (x)", true);
		radioObstacle.setFont(font);
		radioClear = new JRadioButton("Clear (c)", true);
		radioClear.setFont(font);

		buttonGroupEditMode = new ButtonGroup();
		buttonGroupEditMode.add(radioEnd);
		buttonGroupEditMode.add(radioObstacle);
		buttonGroupEditMode.add(radioStart);
		buttonGroupEditMode.add(radioClear);
		radioEnd.setBackground(Color.LIGHT_GRAY);
		radioStart.setBackground(Color.LIGHT_GRAY);
		radioObstacle.setBackground(Color.LIGHT_GRAY);
		radioClear.setBackground(Color.LIGHT_GRAY);
		panelEditMode.add(radioStart);
		panelEditMode.add(radioEnd);
		panelEditMode.add(radioObstacle);
		panelEditMode.add(radioClear);
		radioStart.setFocusable(false);
		radioEnd.setFocusable(false);
		radioClear.setFocusable(false);
		radioObstacle.setFocusable(false);
		panelSettings.add(panelEditMode);

		// WorldEdit
		panelWorldEdit = new JPanel();
		panelWorldEdit.setBackground(Color.LIGHT_GRAY);
		panelWorldEdit.setLayout(new GridLayout(4, 2));
		panelWorldEdit.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));

		JLabel labelSize = new JLabel(" Size: ");
		JLabel labelType = new JLabel(" Type: ");
		JLabel labelPercentage = new JLabel(" Percentage: ");

		labelSize.setFont(font);
		labelType.setFont(font);
		labelPercentage.setFont(font);

		panelWorldEdit.add(labelSize);

		comboWorldSize = new JComboBox<String>(sizes);
		comboWorldSize.setFocusable(false);
		comboWorldSize.setFont(font);
		comboWorldSize.setEnabled(false);                   //HERE
		panelWorldEdit.add(comboWorldSize);
		panelWorldEdit.add(labelType);
		comboWorldType = new JComboBox<String>(worldType);
		comboWorldType.setFocusable(false);
		comboWorldType.setFont(font);
		panelWorldEdit.add(comboWorldType);

		// spinnerPercentageValue = new JSpinner(new
		// SpinnerNumberModel(25,5,95,5));
		// spinnerPercentageValue.setFocusable(false);
		// panelWorldEdit.add(spinnerPercentageValue);
		panelWorldEdit.add(labelPercentage);
		comboPercentage = new JComboBox<String>(percentage);
		comboPercentage.setFocusable(false);
		comboPercentage.setFont(font);
		panelWorldEdit.add(comboPercentage);
		
		buttonClearWorld = new JButton("Clear");
		buttonClearWorld.setFocusable(false);
		buttonClearWorld.setFont(font);
		buttonClearWorld.setActionCommand("clear");
		buttonClearWorld.addActionListener(this);
		panelWorldEdit.add(buttonClearWorld);
		
		buttonGenerateWorld = new JButton("Generate");
		buttonGenerateWorld.setFocusable(false);
		buttonGenerateWorld.setFont(font);
		buttonGenerateWorld.setActionCommand("generate");
		buttonGenerateWorld.addActionListener(this);
		panelWorldEdit.add(buttonGenerateWorld);
		panelSettings.add(panelWorldEdit);
		
		//Simulation
		panelSimulation = new JPanel();
		panelSimulation.setBackground(Color.LIGHT_GRAY);
		panelSimulation.setLayout(new GridLayout(2, 2));
		panelSimulation.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
		
		
		//subPanelSimulation.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
		
		sliderSimSpeed = new JSlider();
		sliderSimSpeed.setMinimum(1);
		sliderSimSpeed.setMaximum(20);
		sliderSimSpeed.setFocusable(false);
		labelSimSpeed = new JLabel("");
		labelSimSpeed.setFont(font);
		labelSimSpeed.setFocusable(false);
		sliderSimSpeed.addChangeListener(new ChangeListener() {
			
			@Override
			public void stateChanged(ChangeEvent arg0) {
				labelSimSpeed.setText(" Speed: " + sliderSimSpeed.getValue());
			}
		});
		sliderSimSpeed.setBackground(Color.LIGHT_GRAY);
		
		
		
		panelSimulation.add(labelSimSpeed);
		
		buttonEndSim = new JButton("End");
		buttonEndSim.setFocusable(false);
		buttonStartSim = new JButton("Start");
		buttonStartSim.setFocusable(false);
		buttonEndSim.addActionListener(this);
		buttonStartSim.addActionListener(this);
		buttonEndSim.setActionCommand("end");
		buttonStartSim.setActionCommand("start");
		
		panelSimulation.add(buttonStartSim);
		
		
		
		
		panelSettings.add(panelSimulation);

		

		

		add(panelSettings);
		setVisible(true);
		// mainView.setPreferredSize(new Dimension(100,100));
		panelMainView = new MainView();

		// panelMain.setSize(new
		// Dimension(getWidth()-settingsWidth,getHeight()-35));
		add(panelMainView);

		addKeyListener(PV.getKeyListener());
		this.setFocusable(true);
		this.requestFocusInWindow();
		repaint();

	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getActionCommand().equals("generate")) {
			/*
			getMainView().setVisible(false);
			if (getComboWorldSize().getSelectedItem().equals("10x10")) {
				PV.setFieldHeight(10);
				PV.setFieldWidth(10);
				PV.setNodeSize(80);
				//PV.setNodeNet(FieldGenerator); 
				//PV.setNodeNet(null);
				//PV.setNodeNet(FieldGenerator.createEmpty());
				//PV.getNodeNet() = FieldGenerator.createEmpty();
			}
			PV.initNodeNet();
			getMainView().setVisible(true);
			PV.setNodeNet(FieldGenerator.createEmpty());
			setMainView(new MainView());
			
			getMainView().repaint();
			//getMainView().repaint();*/
			if(getComboWorldType().getSelectedItem().equals("Clear")){
				FieldGenerator.clearNodeNet(true);
				//getMainView().repaint();
			}
			if(getComboWorldType().getSelectedItem().equals("Random")){
				FieldGenerator.clearNodeNet(true);
				FieldGenerator.createRandomMaze(Integer.parseInt(getComboPercentage().getSelectedItem().toString()));
				getMainView().repaint();
			}
			if(getComboWorldType().getSelectedItem().equals("Structured")){
				FieldGenerator.clearNodeNet(true);
				FieldGenerator.createLogicMaze(Integer.parseInt(getComboPercentage().getSelectedItem().toString()));
				getMainView().repaint();
			}
			if(getComboWorldType().getSelectedItem().equals("Fill")){
				FieldGenerator.fillMaze();
				getMainView().repaint();
			}
		}else if(e.getActionCommand().equals("clear")){
			FieldGenerator.clearNodeNet(false);
			getMainView().repaint();
		}else if(e.getActionCommand().equals("start")){
			//System.out.println("start");
			FieldGenerator.clearNodeNet(false);
			PathFinder finder = new PathFinder();
			finder.getaStarThread().start();
			while(finder.getaStarThread().isAlive()){
				//doNothing GODDAMMIT
			}
			
			getMainView().repaint();
			
		}

	}

	@Override
	public void paint(Graphics g) {

		super.paint(g);

		if (panelMainView instanceof MainView) {

			panelMainView.setSize(new Dimension(getWidth() - settingsWidth, getHeight()));
			// panelMainView.repaint();
			// System.out.println(panelMainView.getSize());
		}
		if (panelSettings instanceof JPanel) {
			panelSettings.setLocation(this.getWidth() - settingsWidth, 0);
			panelSettings.setSize(settingsWidth, this.getHeight());

		}

	}

	public JPanel getPanelSettings() {
		return panelSettings;
	}

	public void setPanelSettings(JPanel panelSettings) {
		this.panelSettings = panelSettings;
	}

	public JPanel getPanelTitle() {
		return panelTitle;
	}

	public void setPanelTitle(JPanel panelTitle) {
		this.panelTitle = panelTitle;
	}

	public MainView getMainView() {
		return panelMainView;
	}

	public void setMainView(MainView mainView) {
		this.panelMainView = mainView;
	}

	public int getSettingsWidth() {
		return settingsWidth;
	}

	public JPanel getPanelInfo1() {
		return panelInfo1;
	}

	public void setPanelInfo1(JPanel panelInfo1) {
		this.panelInfo1 = panelInfo1;
	}

	public JLabel getLabelFCosts() {
		return labelFCosts;
	}

	public void setLabelFCosts(JLabel labelFCosts) {
		this.labelFCosts = labelFCosts;
	}

	public JLabel getLabelGCosts() {
		return labelGCosts;
	}

	public void setLabelGCosts(JLabel labelGCosts) {
		this.labelGCosts = labelGCosts;
	}

	public JLabel getLabelHCosts() {
		return labelHCosts;
	}

	public void setLabelHCosts(JLabel labelHCosts) {
		this.labelHCosts = labelHCosts;
	}

	public MainView getPanelMainView() {
		return panelMainView;
	}

	public void setPanelMainView(MainView panelMainView) {
		this.panelMainView = panelMainView;
	}

	public JRadioButton getRadioObstacle() {
		return radioObstacle;
	}

	public void setRadioObstacle(JRadioButton radioObstacle) {
		this.radioObstacle = radioObstacle;
	}

	public JRadioButton getRadioStart() {
		return radioStart;
	}

	public void setRadioStart(JRadioButton radioStart) {
		this.radioStart = radioStart;
	}

	public JRadioButton getRadioEnd() {
		return radioEnd;
	}

	public void setRadioEnd(JRadioButton radioEnd) {
		this.radioEnd = radioEnd;
	}

	public JRadioButton getRadioClear() {
		return radioClear;
	}

	public void setRadioClear(JRadioButton radioClear) {
		this.radioClear = radioClear;
	}

	public JPanel getPanelEditMode() {
		return panelEditMode;
	}

	public void setPanelEditMode(JPanel panelEditMode) {
		this.panelEditMode = panelEditMode;
	}

	public ButtonGroup getButtonGroupEditMode() {
		return buttonGroupEditMode;
	}

	public void setButtonGroupEditMode(ButtonGroup buttonGroupEditMode) {
		this.buttonGroupEditMode = buttonGroupEditMode;
	}

	public JPanel getPanelWorldEdit() {
		return panelWorldEdit;
	}

	public void setPanelWorldEdit(JPanel panelWorldEdit) {
		this.panelWorldEdit = panelWorldEdit;
	}

	public JComboBox<String> getComboWorldSize() {
		return comboWorldSize;
	}

	public void setComboWorldSize(JComboBox<String> comboWorldSize) {
		this.comboWorldSize = comboWorldSize;
	}

	public String[] getSizes() {
		return sizes;
	}

	public void setSizes(String[] sizes) {
		this.sizes = sizes;
	}

	public JButton getButtonGenerateWorld() {
		return buttonGenerateWorld;
	}

	public void setButtonGenerateWorld(JButton buttonGenerateWorld) {
		this.buttonGenerateWorld = buttonGenerateWorld;
	}

	public String[] getWorldType() {
		return worldType;
	}

	public void setWorldType(String[] worldType) {
		this.worldType = worldType;
	}

	public JComboBox<String> getComboWorldType() {
		return comboWorldType;
	}

	public void setComboWorldType(JComboBox<String> comboWorldType) {
		this.comboWorldType = comboWorldType;
	}

	public String[] getPercentage() {
		return percentage;
	}

	public void setPercentage(String[] percentage) {
		this.percentage = percentage;
	}

	public JComboBox<String> getComboPercentage() {
		return comboPercentage;
	}

	public void setComboPercentage(JComboBox<String> comboPercentage) {
		this.comboPercentage = comboPercentage;
	}

	public Font getFont() {
		return font;
	}

	public void setFont(Font font) {
		this.font = font;
	}

}
